package com.sicau.smarttraceplatform.utils;

import com.aliyun.oss.*;
import com.aliyun.oss.model.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class AliOSSUtil {
    // Endpoint以杭州为例，其它Region请按实际情况填写。
    private static final String END_POINT = "http://oss-cn-hangzhou.aliyuncs.com";
    // 阿里云主账号AccessKey拥有所有API的访问权限，风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维，请登录 https://ram.console.aliyun.com 创建RAM账号。
    private static final String ACCESS_KEYID = "LTAIS4oAvdArJrMM";
    private static final String ACCESS_KEYSECRET = "h5TyFJKUUFDRI1g3SrLp5Mu63DnO9S";
    private static final String BUCKET_NAME = "smart-trace";

    /**
     * 创建文件夹
     * @param keySuffixWithSlash
     */
    public static void createFoler(String keySuffixWithSlash){
        OSS client = new OSSClientBuilder().build(END_POINT, ACCESS_KEYID, ACCESS_KEYSECRET);

        try {
            /*
             * Create an empty folder without request body, note that the key must be
             * suffixed with a slash
             */
//            final String keySuffixWithSlash = "MyObjectKey/";
            client.putObject(BUCKET_NAME, keySuffixWithSlash, new ByteArrayInputStream(new byte[0]));
            System.out.println("Creating an empty folder " + keySuffixWithSlash + "\n");

            /*
             * Verify whether the size of the empty folder is zero
             */
            OSSObject object = client.getObject(BUCKET_NAME, keySuffixWithSlash);
            System.out.println("Size of the empty folder '" + object.getKey() + "' is " +
                    object.getObjectMetadata().getContentLength());
            object.getObjectContent().close();

        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message: " + oe.getErrorCode());
            System.out.println("Error Code:       " + oe.getErrorCode());
            System.out.println("Request ID:      " + oe.getRequestId());
            System.out.println("Host ID:           " + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message: " + ce.getMessage());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            /*
             * Do not forget to shut down the client finally to release all allocated resources.
             */
            client.shutdown();
        }
    }

    /**
     * 批量删除文件
     * @param keys 包含文件名的list
     */
    public static List<String> deleteObjects(List<String> keys){
        // 创建OSSClient实例。
        OSSClient ossClient = new OSSClient(END_POINT, ACCESS_KEYID, ACCESS_KEYSECRET);

        DeleteObjectsResult deleteObjectsResult = ossClient.deleteObjects(new DeleteObjectsRequest(BUCKET_NAME).withKeys(keys));

        //删除了的object数组
        List<String> deletedObjects = deleteObjectsResult.getDeletedObjects();

        // 关闭OSSClient。
        ossClient.shutdown();

        return deletedObjects;
    }

    /**
     * 删除单个文件
     * @param objectName
     */
    public static void deleteObject(String objectName){
        // 创建OSSClient实例。
        OSSClient ossClient = new OSSClient(END_POINT, ACCESS_KEYID, ACCESS_KEYSECRET);
        // 删除文件。
        ossClient.deleteObject(BUCKET_NAME, objectName);

        // 关闭OSSClient。
        ossClient.shutdown();

    }

    /**
     * 列举指定前缀指定个数文件
     * @param keyPrefix  文件前缀
     * @param maxKeys    列举文件的数量，最大为1000，如果为null列举全部
     * @return  查询到的文件列表
     */
    public static List<String> listObjectsWithin(String keyPrefix,Integer maxKeys){
        // 创建OSSClient实例。
        OSSClient ossClient = new OSSClient(END_POINT, ACCESS_KEYID, ACCESS_KEYSECRET);

        List<String> list = new ArrayList<>();

        //如果未null则列举全部
        if (maxKeys==null){
            ObjectListing objectListing;
            String nextMarker = null;
            do {
                objectListing = ossClient.listObjects(new ListObjectsRequest(BUCKET_NAME).
                        withPrefix(keyPrefix).withMarker(nextMarker));
                List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
                for (OSSObjectSummary s : sums) {
                    System.out.println("\t" + s.getKey());
                    list.add(s.getKey());
                }
                nextMarker = objectListing.getNextMarker();

            } while (objectListing.isTruncated());
        }else {
            // 列举包含指定前缀的文件。
            ObjectListing objectListing = ossClient.listObjects(new ListObjectsRequest(BUCKET_NAME).withPrefix(keyPrefix).withMaxKeys(maxKeys));
            List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
            for (OSSObjectSummary s : sums) {
                System.out.println("\t" + s.getKey());
                list.add(s.getKey());
            }
        }

        // 关闭OSSClient。
        ossClient.shutdown();
        return list;
    }


    /**
     * 复制文件
     * @param sourceObjectName 文件原来的位置
     * @param destinationObjectName 文件的目标文职
     */
    public static void copyObject(String sourceObjectName,String destinationObjectName){
        // 创建OSSClient实例。
        OSSClient ossClient = new OSSClient(END_POINT, ACCESS_KEYID, ACCESS_KEYSECRET);

        // 拷贝文件。
        CopyObjectResult result = ossClient.copyObject(BUCKET_NAME, sourceObjectName, BUCKET_NAME, destinationObjectName);
        System.out.println("ETag: " + result.getETag() + " LastModified: " + result.getLastModified());

        // 关闭OSSClient。
        ossClient.shutdown();
    }

    /**
     * 上传文件
     * @param multipartFile 需要上传的文件
     * @param objectName 文件路径
     */
    public static boolean uploadObject(MultipartFile multipartFile,String objectName){
        // 创建OSSClient实例。
        OSSClient ossClient = new OSSClient(END_POINT, ACCESS_KEYID, ACCESS_KEYSECRET);
        // 上传文件。<yourLocalFile>由本地文件路径加文件名包括后缀组成，例如/users/local/myfile.txt。
        try {
            ossClient.putObject(BUCKET_NAME, objectName, multipartFile.getInputStream());
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        } finally {
            // 关闭OSSClient。
            ossClient.shutdown();
        }

        return true;
    }

//    public static void setObjectAccess(String objectName,String status){
//        // 创建OSSClient实例。
//        OSSClient ossClient = new OSSClient(END_POINT, ACCESS_KEYID, ACCESS_KEYSECRET);
//        if(status.equals("1")){
//            // 设置文件的访问权限为公共读。
//            ossClient.setObjectAcl(BUCKET_NAME, objectName, CannedAccessControlList.PublicRead);
//        }else if (status.equals("0")){
//            // 设置文件的访问权限为私有。
//            ossClient.setObjectAcl(BUCKET_NAME, objectName, CannedAccessControlList.Private);
//        }
//        ossClient.shutdown();
//    }

    public static boolean isExist(String object){
        // 创建OSSClient实例。
        OSSClient ossClient = new OSSClient(END_POINT, ACCESS_KEYID, ACCESS_KEYSECRET);

        // 判断文件是否存在。doesObjectExist还有一个参数isOnlyInOSS，如果为true则忽略302重定向或镜像；如果为false，则考虑302重定向或镜像。
        boolean found = ossClient.doesObjectExist(BUCKET_NAME, object);
        System.out.println(found);

        // 关闭OSSClient。
        ossClient.shutdown();
        return found;
    }

}
